<template><div><h2 id="前言" tabindex="-1"><a class="header-anchor" href="#前言" aria-hidden="true">#</a> 前言</h2>
<p>因为<a href="https://github.com/lzyzsd/JsBridge" target="_blank" rel="noopener noreferrer">JsBridge<ExternalLinkIcon/></a>里的<code v-pre>example</code>内容很多，自己第一次看这个东西，一下子还是一头雾水的，关于<code v-pre>Android</code>与<code v-pre>JavaScript</code>的交互，之前都是直接使用<code v-pre>WebView</code>来实现的，可是后来并没有深入去研究这个东西，原先项目使用到的<code v-pre>WebView</code>，也因为紧紧只是展示<code v-pre>html</code>页面，为了优化，也换成了<a href="https://x5.tencent.com" target="_blank" rel="noopener noreferrer">TBS 腾讯浏览服务<ExternalLinkIcon/></a>，之后再也没接触到 Android 与 JS 交互相关的知识，就趁这个机会，把这方面的一点一点心得记录一下。</p>
<h2 id="准备工作" tabindex="-1"><a class="header-anchor" href="#准备工作" aria-hidden="true">#</a> 准备工作</h2>
<p>1.首先，需要在根目录下的<code v-pre>build.gradle</code>文件中加上：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>repositories {
    // ...
    maven { url "https://jitpack.io" }
}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>2.然后，需要在<code v-pre>app</code>目录下的<code v-pre>build.gradle</code>文件中加上依赖：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>implementation 'com.github.lzyzsd:jsbridge:1.0.4'
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h2 id="开始使用" tabindex="-1"><a class="header-anchor" href="#开始使用" aria-hidden="true">#</a> 开始使用</h2>
<p><strong>一、实现通过 JavaScript 调用 Android 方法</strong></p>
<p>1.在<code v-pre>src/main</code>文件夹下新建一个<code v-pre>assets</code>文件夹，然后在里面新建一个<code v-pre>demo.html</code>文件，内容如下所示：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>&lt;html>
&lt;head>
    &lt;meta content="text/html; charset=utf-8" http-equiv="content-type" />
&lt;/head>

&lt;body style="background-color:antiquewhite;">
HTML
&lt;p>
    &lt;input type="button" value="Call Android Method" onclick="testClicked()" />
&lt;/p>
&lt;p style="width: 100%;">
    &lt;span id="show">Show Contents:&lt;/span>
&lt;/p>
&lt;/body>
&lt;script>
    function testClicked() {
      window.WebViewJavascriptBridge.callHandler(
        "jsCallAndroid",
        { name: "weihao" },
        function(responseData) {
          document.getElementById("show").innerHTML = responseData;
        }
      );
    }
    /**
      这个库将把WebViewJavascriptBridge对象注入到窗口对象。
      所以在您的js中，在使用WebViewJavascriptBridge之前，
      必须检测WebViewJavascriptBridge是否存在。
      如果WebViewJavascriptBridge未退出，
      则可以侦听WebViewJavascriptBridgeReady事件
    */
    connectWebViewJavascriptBridge(function(bridge) {
      bridge.init(function(message, responseCallback) {
        if (responseCallback) {
          responseCallback(data);
        }
      });
    });
    function connectWebViewJavascriptBridge(callback) {
      if (window.WebViewJavascriptBridge) {
        callback(WebViewJavascriptBridge);
      } else {
        document.addEventListener(
          "WebViewJavascriptBridgeReady",
          function() {
            callback(WebViewJavascriptBridge);
          },
          false
        );
      }
    }
  &lt;/script>
&lt;/html>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>2.需要在<code v-pre>activity_main.xml</code>文件中，加上布局：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>    &lt;com.github.lzyzsd.jsbridge.BridgeWebView
        android:id="@+id/bridgeWebview"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    &lt;TextView
        android:id="@+id/tv_content"
        app:layout_constraintTop_toBottomOf="@+id/bt_calljs"
        app:layout_constraintLeft_toLeftOf="@+id/bt_calljs"
        android:layout_width="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Content"
        android:layout_height="wrap_content"/>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>3.在<code v-pre>MainActivity.java</code>中注册一个方法<code v-pre>jsCallAndroid</code>，用于<code v-pre>JS</code>调用，并且使用<code v-pre>loadUrl</code>加载<code v-pre>demo.html</code>文件，代码如下所示：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>        bridgeWebview.registerHandler("jsCallAndroid", new BridgeHandler() {
            @Override
            public void handler(String data, CallBackFunction function) {
                tvContent.setText("params from JavaScript: " + data);
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("nickname", "braveheart");
                    jsonObject.put("age", "18");
                    jsonObject.put("address", "China");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                function.onCallBack("return data from Android: "+jsonObject.toString());
            }
        });
        bridgeWebview.loadUrl("file:///android_asset/demo.html");
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>上面主要是为了使<code v-pre>Android</code>与<code v-pre>JS</code>的交互更为形象，所以就模拟成一个网络请求获取用户信息的方式来说明，其意思是，当从<code v-pre>JS</code>调用这个<code v-pre>Android</code>方法<code v-pre>jsCallAndroid</code>时，需要传入参数<code v-pre>data</code>，也就是<code v-pre>{ &quot;name&quot; : &quot;weihao&quot; }</code>，然后会从<code v-pre>Android</code>返回用户信息，也就是：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>{"nickname":"braveheart","age":"18","address":"China"}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>4.运行效果，如下图所示：</p>
<p><img src="@source/android/images/0522_1.png" alt=""></p>
<p>上部分是<code v-pre>demo.html</code>文件页面，下部分是<code v-pre>Android</code>原生页面，其中可以看到，当点击<code v-pre>Call Android Method</code>按钮时，<code v-pre>JS</code>调用<code v-pre>Android</code>方法<code v-pre>jsCallAndroid</code>，<code v-pre>Android</code>页面的<code v-pre>TextView</code>控件获取到了传过来的参数<code v-pre>{ &quot;name&quot; : &quot;weihao&quot; }</code>，并且在<code v-pre>demo.html</code>页面确实从<code v-pre>Android</code>返回了用户信息：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>{"nickname":"braveheart","age":"18","address":"China"}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p><strong>二、实现在 Android 里调用 JavaScript 方法</strong></p>
<p>1.在<code v-pre>activity_main.xml</code>文件中，加上一个<code v-pre>Button</code>控件，代码如下所示：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>    &lt;Button
        android:id="@+id/bt_call_js"
        app:layout_constraintTop_toBottomOf="@+id/tv_android"
        app:layout_constraintLeft_toLeftOf="@+id/tv_android"
        android:layout_width="wrap_content"
        android:textAllCaps="false"
        android:text="Call JavaScript Method"
        android:layout_height="wrap_content"/>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>2.需要在<code v-pre>demo.html</code>文件里的<code v-pre>connectWebViewJavascriptBridge</code>方法里加上一个让<code v-pre>Android</code>调用的方法<code v-pre>androidCallJS</code>，代码如下所示：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>      bridge.registerHandler("androidCallJS", function(data, responseCallback) {
        document.getElementById("show").innerHTML =
          "params from Android：" + data;
        if (responseCallback) {
          var responseData = `{"nickname":"braveheart","age":"18","address":"China"}`;
          responseCallback(responseData);
        }
      });
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>3.在<code v-pre>MainActivity.java</code>中加上如下代码，用于调用<code v-pre>JS</code>里的<code v-pre>androidCallJS</code>方法，代码如下所示：</p>
<div class="language-text ext-text line-numbers-mode"><pre v-pre class="language-text"><code>        btCallJS.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                bridgeWebview.callHandler("androidCallJS","{ name: \"weihao\" }", new CallBackFunction() {
                    @Override
                    public void onCallBack(String data) {
                        tvContent.setText("return data from JavaScript: "+data);
                    }
                });
            }
        });
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以上也是通过模拟网络请求获取用户信息的方式，来形象说明<code v-pre>Android</code>与<code v-pre>JS</code>的交互，只不过改成了从<code v-pre>Android</code>传入用户名，从<code v-pre>JS</code>返回用户信息而已。</p>
<p>4.运行效果，如下图所示：</p>
<p><img src="@source/android/images/0522_2.png" alt=""></p>
</div></template>


